#include "Matrix3.h"
#include "PointLight.h"

PointLight::PointLight()
:
m_location( Vector3::ZERO )
{
}

void PointLight::compute_diffuse( const Matrix3& world_rotate,
								 const Vector3& world_translate,
								 Real world_scale, const Vector3* vertex,
								 const Vector3* normal, unsigned int num_lights,
								 const bool* visible, Color* diffuse )
{
	// transform light position to model space of old mesh
	Real inv_scale = 1.0 / world_scale;
	Vector3 diff = m_location - world_translate;
	Vector3 model_pos = ( diff * world_rotate ) * inv_scale;

	// adjust diffuse color by light intensity
	Color adj_diffuse = m_intensity * m_diffuse;

	for ( unsigned int i = 0; i < num_lights; i++ )
	{
		if ( visible[i] )
		{
			diff = model_pos - vertex[i];
			Real dot = diff.dot( normal[i] );
			if ( dot > 0.0 )
			{
				dot /= diff.length();
				diffuse[i] += dot * adj_diffuse;
			}
		}
	}
}

void PointLight::compute_specular( const Matrix3& world_rotate, const Vector3& world_translate,
								  Real world_scale, const Vector3* vertex, const Vector3* normal,
								  unsigned int num_lights, const bool* visible, const Vector3& camera_model_location,
								  Color* specular )
{ 
	Real inv_scale = 1.0 / world_scale;
	Vector3 diff = m_location - world_translate;
	Vector3 model_pos = ( diff * world_rotate ) * inv_scale;

	// adjust specular color by light intensity 
	Color adj_specular = m_intensity * m_specular;

	for ( unsigned int i = 0; i < num_lights; i++ )
	{
		if ( visible[i] )
		{
			diff = model_pos - vertex[i];
			Real dot = diff.dot( normal[i] );
			Vector3 reflect = (2.0*dot)*normal[i] - diff;
			Vector3 viewdir = camera_model_location - vertex[i];
			if ( dot > 0.0 )
			{
				Real vsl = viewdir.dot( viewdir );
				Real rsl = reflect.dot( reflect );
				Real denom = Math::sqrt_t( vsl * rsl );
				specular[i] += (dot/denom)*adj_specular;
			}
		}
	}
}
